﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace Kokomo.PeInspector.Reflection
{
	/// <summary>
	/// Provides functionality for writing code.
	/// </summary>
	/// <remarks>
	/// This interface provides a layer of abstract for generating
	/// source documents.  The target may be a <see cref="System.Windows.Documents.FlowDocument"/>
	/// to display in the UI, or a text document to save to a file.
	/// <para>
	/// Control indentation using <see cref="Indent"/> and <see cref="Outdent"/>.
	/// </para>
	/// </remarks>
	/// <seealso cref="CodeWriterBase"/>
	/// <seealso cref="TextCodeWriter"/>
	/// <seealso cref="FlowDocumentCodeWriter"/>
	public interface ICodeWriter : IDisposable
	{
		/// <summary>
		/// Writes text to the source document.
		/// </summary>
		/// <param name="text">The text to write.</param>
		/// <param name="textType">The type of text.</param>
		/// <remarks>
		/// The implementation should format the text (if possible)
		/// according to <paramref name="textType"/>.
		/// </remarks>
		void WriteText(string text, CodeTextType textType = CodeTextType.Normal);
		/// <summary>
		/// Writes a reference to member to the source document.
		/// </summary>
		/// <param name="target">The target of the reference.</param>
		/// <param name="text">The text constituting the reference.</param>
		/// <param name="textType">The type of text.</param>
		/// <remarks>
		/// The implementation should format the text (if possible)
		/// according to <paramref name="textType"/>.
		/// Clicking the text should navigate to <paramref name="target"/>.
		/// </remarks>
		void WriteMemberReference(object target, string text, CodeTextType textType = CodeTextType.Normal);
		/// <summary>
		/// Writes a line break to the source document.
		/// </summary>
		void WriteLineBreak();
		/// <summary>
		/// Writes a line break only if the current line already contains text.
		/// </summary>
		void EnsureNewLine();
		/// <summary>
		/// Ensures that the current line has an indent.
		/// </summary>
		void EnsureIndent();
		/// <summary>
		/// Increases the indent level.
		/// </summary>
		/// <remarks>
		/// The new indent level becomes effective after the next line break.
		/// </remarks>
		void Indent();
		/// <summary>
		/// Decreases the indent level.
		/// </summary>
		/// <remarks>
		/// The new indent level becomes effective after the next line break.
		/// </remarks>
		void Outdent();
	}
}
